﻿using System;
using System.Configuration;
using System.Security.Principal;
using System.Web;
using System.Web.Security;
using Cms.Domain.Authentication;
using Cms.Utilities;
using Cms.Web.Framework.Infrastructure;
using iLib.Web.UI;
using log4net.Config;

namespace Cms.Web.UI
{
    public class Global : HttpApplication
    {
        private static Scheduler _scheduler;

        protected void Application_Start(object sender, EventArgs e)
        {
            XmlConfigurator.Configure();
            Application["ActiveSessionCount"] = 0;
            Logging.LogInfo("Application started " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["UseScheduler"]) || ConfigurationManager.AppSettings["UseScheduler"] == "false")
            {
                return;
            }
            _scheduler = new Scheduler();
            _scheduler.Start();
        }

        protected void Session_Start(object sender, EventArgs e)
        {
            Application.Lock();
            Application["ActiveSessionCount"] = (int) Application["ActiveSessionCount"] + 1;
            Application.UnLock();
        }

        protected void Session_End(object sender, EventArgs e)
        {
            Application.Lock();
            Application["ActiveSessionCount"] = (int) Application["ActiveSessionCount"] - 1;
            Application.UnLock();
        }

        protected void Application_AuthenticateRequest(object sender, EventArgs e)
        {
            // Don't do anything if the user is not authenticated or the extension differs from .aspx
            if (!Request.IsAuthenticated || !Url.Page.ToLower().EndsWith(".aspx"))
                return;
            // User is authenticated and extension is .aspx
            var ident = (FormsIdentity) Context.User.Identity;
            string[] roles = ident.Ticket.UserData.Split("|".ToCharArray());
            if (roles[0].Length == 0)
            {
                // Role participation not yet laid down
                AuthenticatedUser user = Conversion.ToAuthenticatedUser(ident.Name);
                if (user.AdministratorID > 0)
                    roles[0] = "Administrator";
                var ticket = new FormsAuthenticationTicket(
                    ident.Ticket.Version,
                    ident.Ticket.Name,
                    ident.Ticket.IssueDate,
                    ident.Ticket.Expiration,
                    ident.Ticket.IsPersistent,
                    string.Join("|", roles),
                    ident.Ticket.CookiePath);
                var authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, FormsAuthentication.Encrypt(ticket))
                                     {
                                         Path = FormsAuthentication.FormsCookiePath + "; HttpOnly; noScriptAccess",
                                         Secure = FormsAuthentication.RequireSSL
                                     };
                if (ticket.IsPersistent)
                    authCookie.Expires = ticket.Expiration;
                Context.Response.Cookies.Add(authCookie);
            }
            HttpContext.Current.User = new GenericPrincipal(ident, roles);
        }

        protected void Application_Error(object sender, EventArgs e)
        {
        }

        protected void Application_End(object sender, EventArgs e)
        {
            Logging.LogInfo("Application ended " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            if (_scheduler != null)
            {
                _scheduler.Dispose();
                _scheduler = null;
            }
            if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["UseScheduler"]) || ConfigurationManager.AppSettings["UseScheduler"] == "false")
            {
                return;
            }
            Scheduler.PingServer();
        }
    }
}